

#import "SURFScanner.h"
#import "UIImage+OpenCV.h"
//#import "iSURFCompareViewController.h"
#include <vector>
@implementation SURFScanner

@synthesize delegate;

+ (SURFScanner*)shared{
    static SURFScanner *_Share = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        if (!_Share) {
            _Share = [[SURFScanner alloc] init];
        }
    });
    
    return _Share;
}

- (void)dealloc 
{
    [super dealloc];
}

- (Boolean) compareImage:(UIImageView *)image11 with:(UIImageView *)image22
{
	NSLog(@"compareImage");
	cv::Mat img1 = [image11.image CVGrayscaleMat];
	cv::Mat img2 = [image22.image CVGrayscaleMat];
	
	cv::SurfFeatureDetector detector(400);
	std::vector<cv::KeyPoint> keypoints1;
	std::vector<cv::KeyPoint> keypoints2;
	NSLog(@"pb2");

	detector.detect(img1, keypoints1);
	detector.detect(img2, keypoints2);

	// computing descriptors
	cv::SurfDescriptorExtractor extractor;
	cv::Mat descriptors1, descriptors2;
	extractor.compute(img1, keypoints1, descriptors1);
	extractor.compute(img2, keypoints2, descriptors2);
		
	NSLog(@"pb3");
	
	double res2 = (double) keypoints1.size();
	double res3 = (double) keypoints2.size();
	
	///////////////////////////////////////////////////////////////////
	NSLog(@"keypoints1 : %f, keypoints2 : %f", res2, res3);
		
	cv::FlannBasedMatcher matcher;
	std::vector< cv::DMatch > smatches;
	matcher.match( descriptors1, descriptors2, smatches );
		
	double max_dist = 0; double min_dist = 100;
	
	//-- Quick calculation of max and min distances between keypoints
	for( int i = 0; i < descriptors1.rows; i++ )
	{ double dist = smatches[i].distance;
		if( dist < min_dist ) min_dist = dist;
		if( dist > max_dist ) max_dist = dist;
	}
	
	NSLog(@"-- Max dist : %f \n", max_dist );
	NSLog(@"-- Min dist : %f \n", min_dist );
		
	cv::BruteForceMatcher<cv::L2<float> > bmatcher;
	std::vector<cv::DMatch> matches;
    bmatcher.match(descriptors1, descriptors2, matches);
	
	//namedWindow("matches", 1);
	cv::Mat img_matches;
	UIImageView *imageRes = [[UIImageView alloc] init];
	 
	cv::drawMatches(img1, keypoints1, img2, keypoints2, matches, img_matches);
	
    imageRes.image = [UIImage imageWithCVMat:img_matches];

	[self.delegate SURFScannerDidFinish:imageRes];
    
	
	
	if (min_dist<0.07) {
		return YES;
	}else {
		return NO;
	}
}

- (Boolean) compare2Image:(UIImage *)image11 with:(UIImage *)image22{
    NSLog(@"compare2Image");
	cv::Mat img1 = [image11 CVGrayscaleMat];
	cv::Mat img2 = [image22 CVGrayscaleMat];
	
	cv::SurfFeatureDetector detector(400);
	std::vector<cv::KeyPoint> keypoints1;
	std::vector<cv::KeyPoint> keypoints2;
	NSLog(@"pb2");
    
	detector.detect(img1, keypoints1);
	detector.detect(img2, keypoints2);
    
	// computing descriptors
	cv::SurfDescriptorExtractor extractor;
	cv::Mat descriptors1, descriptors2;
	extractor.compute(img1, keypoints1, descriptors1);
	extractor.compute(img2, keypoints2, descriptors2);
    
	NSLog(@"pb3");
	
	double res2 = (double) keypoints1.size();
	double res3 = (double) keypoints2.size();
	
	///////////////////////////////////////////////////////////////////
	NSLog(@"keypoints1 : %f, keypoints2 : %f", res2, res3);
    
	cv::FlannBasedMatcher matcher;
	std::vector< cv::DMatch > smatches;
	matcher.match( descriptors1, descriptors2, smatches );
    
	double max_dist = 0; double min_dist = 100;
	
	//-- Quick calculation of max and min distances between keypoints
	for( int i = 0; i < descriptors1.rows; i++ )
	{ double dist = smatches[i].distance;
		if( dist < min_dist ) min_dist = dist;
		if( dist > max_dist ) max_dist = dist;
	}
	
	NSLog(@"-- Max dist : %f \n", max_dist );
	NSLog(@"-- Min dist : %f \n", min_dist );
    
	cv::BruteForceMatcher<cv::L2<float> > bmatcher;
	std::vector<cv::DMatch> matches;
    bmatcher.match(descriptors1, descriptors2, matches);
	
	//namedWindow("matches", 1);
	cv::Mat img_matches;
	UIImageView *imageRes = [[UIImageView alloc] init];
    
	cv::drawMatches(img1, keypoints1, img2, keypoints2, matches, img_matches);
	
    imageRes.image = [UIImage imageWithCVMat:img_matches];
    
	[self.delegate SURFScannerDidFinish:imageRes];
    
	
	
	if (min_dist<0.07) {
		return YES;
	}else {
		return NO;
	}
}

@end
